package com.bolt.support.captcha.impl;

import com.bolt.common.utils.StrUtil;
import com.bolt.convention.exception.BadConfigurationException;
import com.bolt.convention.exception.ServiceException;
import com.bolt.support.captcha.CaptchaExceptionEnum;
import com.bolt.support.captcha.CaptchaProperties;
import com.bolt.support.captcha.CaptchaVO;
import com.wf.captcha.*;
import com.wf.captcha.base.Captcha;

import java.awt.*;
import java.util.UUID;

/**
 * https://gitee.com/whvse/EasyCaptcha
 * EasyCaptcha验证码实现
 */
public class EasyCaptchaServiceImpl extends AbstractCaptchaService {

    private Captcha captcha;


    public EasyCaptchaServiceImpl(CaptchaProperties properties) {
        init(properties);
    }

    @Override
    public void init(CaptchaProperties properties) {
        switch (properties.getCodeType()) {
            case arithmetic:
                // 算术类型 https://gitee.com/whvse/EasyCaptcha
                captcha = new ArithmeticCaptcha(properties.getWidth(), properties.getHeight());
                // 几位数运算，默认是两位
                captcha.setLen(properties.getLength());
                break;
            case chinese:
                captcha = new ChineseCaptcha(properties.getWidth(), properties.getHeight());
                captcha.setLen(properties.getLength());
                break;
            case chinese_gif:
                captcha = new ChineseGifCaptcha(properties.getWidth(), properties.getHeight());
                captcha.setLen(properties.getLength());
                break;
            case gif:
                captcha = new GifCaptcha(properties.getWidth(), properties.getHeight());
                captcha.setLen(properties.getLength());
                break;
            case spec:
                captcha = new SpecCaptcha(properties.getWidth(), properties.getHeight());
                captcha.setLen(properties.getLength());
                break;
            default:
                throw new BadConfigurationException("验证码配置信息错误！正确配置查看 switchCaptcha ");
        }

        if (StrUtil.isNotBlank(properties.getFontName())) {
            captcha.setFont(new Font(properties.getFontName(), Font.PLAIN, properties.getFontSize()));
        }
        captcha.setWidth(properties.getWidth());
        captcha.setHeight(captcha.getHeight());
    }

    @Override
    public CaptchaVO get(CaptchaVO captchaVO) {
        validateGet(captchaVO);
        String uuid = UUID.randomUUID().toString();
        CaptchaVO data = new CaptchaVO();
        data.setCaptchaId(uuid);
        data.setImageBase64(captcha.toBase64());
        CaptchaServiceFactory.getCache().set(uuid, captcha.text(), properties.getExpiration());
        return data;
    }

    /**
     * /**
     * 核对验证码(前端)
     *
     * @param captchaVO
     * @return
     */
    @Override
    public boolean check(CaptchaVO captchaVO) {
        String validateCode = captchaVO.getValidateCode();
        String code = CaptchaServiceFactory.getCache().get(captchaVO.getCaptchaId());
        if (StrUtil.isBlank(code)) {
            afterValidateFail(captchaVO);
            throw new ServiceException(CaptchaExceptionEnum.AUTH_CAPTCHA_EXPIRED_ERROR);
        }
        if (StrUtil.isBlank(validateCode) || !validateCode.equalsIgnoreCase(code)) {
            afterValidateFail(captchaVO);
            throw new ServiceException(CaptchaExceptionEnum.AUTH_CAPTCHA_VERIFY_ERROR);
        }
        return true;
    }

    /**
     * 二次校验验证码(后端)
     *
     * @param captchaVO
     * @return
     */
    @Override
    public boolean verification(CaptchaVO captchaVO) {
        String validateCode = captchaVO.getValidateCode();
        String code = CaptchaServiceFactory.getCache().get(captchaVO.getCaptchaId());
        CaptchaServiceFactory.getCache().delete(captchaVO.getCaptchaId());
        if (StrUtil.isBlank(code)) {
            afterValidateFail(captchaVO);
            throw new ServiceException(CaptchaExceptionEnum.AUTH_CAPTCHA_EXPIRED_ERROR);
        }
        if (StrUtil.isBlank(validateCode) || !validateCode.equalsIgnoreCase(code)) {
            afterValidateFail(captchaVO);
            throw new ServiceException(CaptchaExceptionEnum.AUTH_CAPTCHA_VERIFY_ERROR);
        }
        return true;
    }
}